package com.xpec.c4.service.module.common;

import java.lang.reflect.Type;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.ms.game.gmtool.message.SGmtoolUpdateItemInfos;
import com.ms.game.itembox.ItemBasicAdapter;
import com.ms.game.itembox.container.ItemBasic;
import com.ms.game.itembox.db.ItemDAO;
import com.ms.game.login.bin.ContinuousLoginRewardBinUtil;
import com.ms.service.module.common.message.SPlayerCommonInfo;
//import com.ms.service.module.common.timer.DangerIPListUpdateTask;
import com.ms.service.module.common.timer.OnceTaskTimer;
import com.ms.service.module.common.timer.UpdateTaskTimer;
import com.ms.service.telnet.STelnetCmd;
import com.ms.service.telnet.TelGUID;
import com.xpec.c4.game.utility.GameUtility;
import com.xpec.c4.service.module.BasicServiceModule;
import com.xpec.c4.service.module.task.TaskTimer;

/**
 * 每一個JVM(instance)都有一個此Module<br>
 * 
 * 請手動在server_info.properties設定正確<br>
 *  
 * @author yangbingyan
 *
 */
public class CommonModule extends BasicServiceModule{

	@SuppressWarnings("unused")
	private static final Log log = LogFactory.getLog(CommonModule.class);	

	/**
	 * 
	 */
	private static final int UPDATE_PERIOD = 10 * 1000;
	
	/**
	 * 
	 */
	private static boolean loaded = false;
	
	/**
	 * 开始
	 * 
	 * @return
	 *
	 */
	@Override
	public boolean startup(){
		
		//第一個
		if (isFirstModule()) {
			PlayerCommonInfoManager.initRedisCommon();
		}
		
		registerJmxInfo();
		
		if(!loaded){
			loaded = true;
			super.startup();
		}else{
			return false;
		}
		
		PlayerCommonInfoManager.getInstance().setCommonModule(this);
		
		ItemInfoManager.getInstance().setCommonModule(this);
		ItemInfoManager.getInstance().initItemBox();
		ItemInfoManager.getInstance().checkItemExist();
		ContinuousLoginRewardBinUtil.verifyItems();
		
		//檢查掉落物的bin檔內容
//		ItemRollGroupListUtil.checkItemRallGroupListItem();
		
//		DangerIPListManager.getInstance().setCommonModule(this);
//		DangerIPListManager.getInstance().loadAll();
		
		// update计时器	
		UpdateTaskTimer upd = new UpdateTaskTimer();		
		upd.setTimerOption(TaskTimer.LOOP);		
		upd.setInitialDelay(UPDATE_PERIOD);
		upd.setPeriod(UPDATE_PERIOD);
		upd.setCallback(this);
		addTaskTimer(upd);
		
//		DangerIPListUpdateTask dangerIPListUpdateTask = new DangerIPListUpdateTask();
//		addTaskTimer(dangerIPListUpdateTask, TaskTimer.LOOP,
//				dangerIPListUpdateTask.MODULE_CHECK_PERIOD,
//				dangerIPListUpdateTask.MODULE_CHECK_PERIOD, this);
		
		return true;
	}
	
	/**
	 * 停止
	 * 
	 * @return
	 */
	@Override
	public void shutdown(){
		super.shutdown();
	}

	/**
	 * 初始化
	 * 
	 * @return
	 *
	 */
	@Override
	public void init(){
		super.init();
		
		// 注册相关的class给Action使用
		registerActionClass(CommonAction.class);
	}
	
	/**
	 * call by timerTask
	 */
	public void startupOnce(){		
	}
	
	/**
	 * 
	 */
	public void updateCallback(){
	}
	
	/**
	 * 針對每一個VM Instance只作一次
	 */
	public void onServerChanged(){
	}
	
	/**
	 * 
	 * @param obj
	 */
	public void onPlayerCommonInfoChanged(SPlayerCommonInfo obj){
		
		switch(obj.type){
		
		case SPlayerCommonInfo.REMOVE: 
			// 玩家下線
			PlayerCommonInfoManager.getInstance().removePlayerCommonInfo( obj.accountId,
					obj.guid , obj.session , obj.name);
			break;
		

		case SPlayerCommonInfo.UPDATE: 
			// 可能是玩家上線
			PlayerCommonInfoManager.getInstance().updatePlayerCommonInfo(obj.accountId,
					obj.guid, obj.session, obj.name, obj.userType);
			break;
		

		case SPlayerCommonInfo.UPDATE_ZONE_ID: 
			// 更新當前地圖
			PlayerCommonInfoManager.getInstance().updatePlayerZoneId(
					obj.guid, obj.zoneId);
			break;
			
//		case SPlayerCommonInfo.DISCONNECT_OWN_CHANNEL_SAVE:
//			//離線者如果是創頻者，要記錄離線時間
//			PlayerCommonInfoManager.getInstance().disconnectOwnChannelSave(obj.guid, obj.accountId, obj.time, obj.channelID);
//			break;

		default:
			break;
			
		}
	}

	/**
	 * 更新道具箱
	 */
	public void onUpdateItemBox(SGmtoolUpdateItemInfos updateItemInfos){
		try{
			
			if(log.isInfoEnabled()) {
				log.info("Start Update Item Box!");
			}
			
			Gson gson = new GsonBuilder().registerTypeAdapter(ItemBasic.class, new ItemBasicAdapter()).create();
			String itemBoxJson = ItemDAO.readItemBoxJsonFromRedis(updateItemInfos.getSubKey());
			
			if(updateItemInfos.isSingleUpdate()){
				ItemBasic item = gson.fromJson(itemBoxJson, ItemBasic.class);
				ItemInfoManager.getInstance().setUpdateing(true);
				ItemInfoManager.getInstance().updateItemBox(item, updateItemInfos.getType());
			}else {
				Type type = new TypeToken<ConcurrentHashMap<String, ItemBasic>>(){}.getType();
				ConcurrentHashMap<String, ItemBasic> newItemBox = gson.fromJson(itemBoxJson, type);
				ItemInfoManager.getInstance().setUpdateing(true);
				//鎖住itembox 然後更新
				ItemInfoManager.getInstance().updateItemBox(newItemBox);
			}

		} catch (Exception e) {
			ItemInfoManager.getInstance().setUpdateing(false);

			if(log.isErrorEnabled()) {
				log.error(GameUtility.getCurMethodName() + "GmTool Update ItemBox Fail!", e);
			}
		}
		
		if(log.isInfoEnabled()) {
			log.info("Item Box Update Finish!");
		}
	}
	
	
	@Override
	public void onModuleServerReadyStart() {
		super.onModuleServerReadyStart();
		
		OnceTaskTimer onceTimer = new OnceTaskTimer();
		onceTimer.setTimerOption(TaskTimer.ONCE);		
		onceTimer.setInitialDelay(UPDATE_PERIOD);
		onceTimer.setPeriod(UPDATE_PERIOD);
		onceTimer.setCallback(this);
		addTaskTimer(onceTimer);
	}

	/**
	 * 返回當前狀態
	 */
	private void feedbackStatus(TelGUID guid) {
		telnetString(guid, ".");
	}
	
	@Override
	public void procTelnetCommand(STelnetCmd obj) {
	}

	@Override
	public void procThrowException(Object obj) {
		// TODO Auto-generated method stub
		
	}
}
